/**
 * Copyright (C) 2012 The SkyTvOS Project
 * <p/>
 * Version     Date           Author
 * ─────────────────────────────────────
 * 2014年6月30日         Root.Lu
 */

package com.tianci.appstore.controller.manager;

import android.os.RemoteException;

import com.coocaa.x.app.framework.app.LiteAppApplication;
import com.coocaa.x.framework.app.CoocaaApplication;
import com.coocaa.x.framework.utils.PMUtils;
import com.coocaa.x.service.XServiceManager;
import com.coocaa.x.service.litedownloader.aidl.IDownloaderServiceListener;
import com.coocaa.x.service.litedownloader.data.DownloadError;
import com.coocaa.x.service.litedownloader.data.DownloadExtra;
import com.coocaa.x.service.litedownloader.data.DownloadTask;
import com.coocaa.x.service.litedownloader.data.ProcessInfo;
import com.coocaa.x.service.litepm.aidl.ILitePMInstallListener;
import com.coocaa.x.service.litepm.data.AppInfo;
import com.coocaa.x.service.litepm.data.InstallParams;
import com.tianci.appstore.controller.AppStoreBaseController;
import com.tianci.appstore.ui.data.SkyAppDetailData.AppStatus;
import com.tianci.appstore.ui.data.SkyListAppData.ListType;
import com.tianci.appstore.ui.data.SkyListProgressData;
import com.tianci.appstore.ui.detail.AppDownloadListener;
import com.tianci.appstore.ui.list.download.DownloadListDataListener;
import com.tianci.appstore.ui.widget.TipToast;
import com.tianci.appstore.utils.AppDebug;
import com.tianci.appstore.utils.Tools;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

public class DownloadManagerController extends AppStoreBaseController {
    private static DownloadManagerController instance = new DownloadManagerController();

    public static DownloadManagerController getInstance() {
        return instance;
    }

    public enum ACTION {
        /**
         * @Fields DOWNLOAD_ALL TODO 开始全部
         */
        DOWNLOAD_ALL,
        /**
         * @Fields PAUSE_ALL TODO 暂停全部
         */
        PAUSE_ALL,
        /**
         * @Fields PAUSE TODO暂停某一个
         */
        PAUSE,
        /**
         * @Fields START TODO开始某一个
         */
        START,
        /**
         * @Fields DELETE TODO 取消某一个
         */
        DELETE,
        /**
         * @Fields TO_FIRST TODO优先某一个
         */
        TO_FIRST,
        /**
         * @Fields INSTALL TODO 安装某一个
         */
        INSTALL,
    }

    private DownloadListDataListener datalistener = null;
    private AppDownloadListener downloadlistener = null;
    private HashMap<String, DownloadTask> taskMap = new HashMap<String, DownloadTask>();

    public void init(DownloadListDataListener listener, AppDownloadListener downloadlistener) {
        datalistener = listener;
        this.downloadlistener = downloadlistener;
        runOnThread(new Runnable() {
            @Override
            public void run() {
                // TODO Auto-generated method stub
                try {
                    XServiceManager.getDownloaderService().setListener(downloaderStub);
                    XServiceManager.getLitePMService().addInstallListener(appPMstub);
                } catch (RemoteException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                updateUI();
            }
        });
    }

    private void update() throws RemoteException {
        int activeCount = 0;
        int pauseCount = 0;
        List<DownloadTask> list = XServiceManager.getDownloaderService().getTaskList();
        if (list != null) {
            for (DownloadTask task : list) {
                task = XServiceManager.getDownloaderService().refresh(task);
                switch (task.info.state) {
                    case CREATE:
                        break;
                    case READY:
                    case PREPARED:
                    case PROCESSING:
                        activeCount++;
                        break;
                    case STOPED:
                        pauseCount++;
                        break;
                    case FINISH:
                        break;
                    default:
                        continue;
                }
            }
            DownloadManagerController.this.datalistener.onRefreshDownloadCount(activeCount,
                    pauseCount, 0);

        }
    }

    private void updateUI() {
        int activeCount = 0;
        int pauseCount = 0;
        List<SkyListProgressData> dataList = new ArrayList<SkyListProgressData>();
        try {
            List<DownloadTask> list = XServiceManager.getDownloaderService().getTaskList();
            synchronized (taskMap) {
                taskMap.clear();
            }
            if (list != null) {
                for (DownloadTask task : list) {
                    task = XServiceManager.getDownloaderService().refresh(task);
                    DownloadExtra extra = DownloadExtra.parseJObject(task.extra,
                            DownloadExtra.class);
                    synchronized (taskMap) {
                        taskMap.put(extra.pkgname, task);
                    }
                    SkyListProgressData data = new SkyListProgressData(ListType.DOWNLOAD_LIST);
                    data.setIconUrl(extra.iconUrl);
                    data.setId(task.url);
                    data.setPkgName(extra.pkgname);
                    data.setTitle(extra.title);
                    data.setObject(task);
                    switch (task.info.state) {
                        case READY:
                            data.setStatus(AppStatus.WAITING);
                            break;
                        case PROCESSING:
                            activeCount++;
                            data.setShowInfo(Tools.fixFloat((float) task.info.length
                                    / (1024.00f * 1024.00f))
                                    + "MB");
                            data.setStatus(AppStatus.DOWNLOADING);
                            if (task.info.length > 0) {
                                int percent = (int) (task.info.current * 100 / task.info.length);
                                data.setPercent(percent);
                            }
                            break;
                        case STOPED:
                            data.setStatus(AppStatus.DOWNLOAD_PAUSED);
                            pauseCount++;
                            break;
                        case FINISH:
                            data.setStatus(AppStatus.DOWNLOADED);
                            break;
                        case CREATE:
                        default:
                            break;
                    }
                    AppStatus status = AppStatus.NOT_DOWNLOADED;
                    switch (XServiceManager.getLitePMService().getAppInstallState(extra.pkgname)) {
                        case PMUtils.INSTALL_STATE_INSTALLING:
                            status = AppStatus.INSTALLING;
                            break;
                        default:
                            break;
                    }
                    switch (status) {
                        case INSTALLING:
                            data.setStatus(AppStatus.INSTALLING);
                            break;
                        default:
                            break;
                    }
                    dataList.add(data);
                }
                // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!注意这个地方，中间的参数改成暂停应用总数
            }
        } catch (RemoteException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        DownloadManagerController.this.datalistener.onDownloadListLoaded(activeCount, pauseCount,
                0, dataList);
    }

    @Override
    public void destroy() {
        // TODO Auto-generated method stub
        runOnThread(new Runnable() {
            @Override
            public void run() {
                // TODO Auto-generated method stub
                try {
                    XServiceManager.getDownloaderService().clearListener(downloaderStub);
                    // AppDataProvider.getInstance().getServiceData()
                    // .clearDownloaderListener(DownloadManagerController.this);
                    // AppDataProvider.getInstance().getServiceData()
                    // .clearAppInstallListener(DownloadManagerController.this);
                } catch (RemoteException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        });
        datalistener = new DownloadListDataListener() {
            @Override
            public void onDownloadListLoaded(int activeCount, int pauseCount, int otherCount, List<SkyListProgressData> dataList) {

            }

            @Override
            public void onRefreshDownloadCount(int activeCount, int pauseCount, int otherCount) {

            }

            @Override
            public void onRefreshShowInfo(String appId, String showInfo) {

            }
        };
        downloadlistener = new AppDownloadListener() {
            @Override
            public void onUpdateStatus(String appId, AppStatus status) {

            }

            @Override
            public void onUpdatePercent(String appId, int percent) {

            }
        };
    }

    /**
     * @param action
     * @param data   除去action包含ALL的选项，都要带上一个指定的data，不能为空！
     * @Description TODO 处理UI的时间，由ui调用
     * @date 2014年7月2日
     */
    public void handleAction(final ACTION action, final SkyListProgressData data) {
        runOnThread(new Runnable() {
            @Override
            public void run() {
                // TODO Auto-generated method stub
                try {
                    DownloadTask task = null;
                    sendBtnClickLOG(action.toString());
                    // LogAPIForAppStore.btnClick(mContext, LOG_PAGENAME, action.toString());
                    switch (action) {
                        case DOWNLOAD_ALL: {
                            sendBtnClickLOG("全部下载");
                            if (!LiteAppApplication.checkNetworkConnection(TipToast.showNetIsNotConnectedToastRunnable))
                                break;
                            XServiceManager.getDownloaderService().startAll();
                            break;
                        }
                        case PAUSE_ALL: {
                            sendBtnClickLOG("全部暂停");
                            if (!LiteAppApplication.checkNetworkConnection(TipToast.showNetIsNotConnectedToastRunnable))
                                break;
                            XServiceManager.getDownloaderService().stopAll();
                            break;
                        }
                        case START: {
                            if (!LiteAppApplication.checkNetworkConnection(TipToast.showNetIsNotConnectedToastRunnable))
                                break;
                            task = (DownloadTask) data.getObject();
                            task = XServiceManager.getDownloaderService().refresh(task);
                            DownloadExtra extra = DownloadExtra.parseJObject(task.extra,
                                    DownloadExtra.class);
                            sendBtnClickLOG("开始下载", Integer.valueOf(extra.appid), extra.title);
                            AppDebug.debug("^^^^^^^^^^^^^^^^^^^^^^^^start ret:"
                                    + XServiceManager.getDownloaderService().start(task));
                            // updateUI();
                            break;
                        }
                        case PAUSE: {
                            if (!LiteAppApplication.checkNetworkConnection(TipToast.showNetIsNotConnectedToastRunnable))
                                break;
                            task = (DownloadTask) data.getObject();
                            task = XServiceManager.getDownloaderService().refresh(task);
                            DownloadExtra extra = DownloadExtra.parseJObject(task.extra,
                                    DownloadExtra.class);
                            sendBtnClickLOG("暂停下载", Integer.valueOf(extra.appid), extra.title);
                            XServiceManager.getDownloaderService().stop(task);
                            // updateUI();
                            break;
                        }
                        case DELETE: {
                            if (!LiteAppApplication.checkNetworkConnection(TipToast.showNetIsNotConnectedToastRunnable))
                                break;
                            task = (DownloadTask) data.getObject();
                            task = XServiceManager.getDownloaderService().refresh(task);
                            DownloadExtra extra = DownloadExtra.parseJObject(task.extra,
                                    DownloadExtra.class);
                            sendBtnClickLOG("取消下载", Integer.valueOf(extra.appid), extra.title);
                            XServiceManager.getDownloaderService().delete(task);
                            // updateUI();
                            break;
                        }
                        case TO_FIRST: {
                            if (!LiteAppApplication.checkNetworkConnection(TipToast.showNetIsNotConnectedToastRunnable))
                                break;
                            task = (DownloadTask) data.getObject();
                            task = XServiceManager.getDownloaderService().refresh(task);
                            DownloadExtra extra = DownloadExtra.parseJObject(task.extra,
                                    DownloadExtra.class);
                            sendBtnClickLOG("优先下载", Integer.valueOf(extra.appid), extra.title);
                            XServiceManager.getDownloaderService().toFirst(task);
                            // updateUI();
                            break;
                        }
                        case INSTALL: {
                            task = (DownloadTask) data.getObject();
                            task = XServiceManager.getDownloaderService().refresh(task);
                            DownloadExtra extra = DownloadExtra.parseJObject(task.extra,
                                    DownloadExtra.class);
                            sendBtnClickLOG("安装", Integer.valueOf(extra.appid), extra.title);
                            InstallParams params = new InstallParams();
                            params.setFrom(InstallParams.INSTALL_FROM.COOCAA_MARKET);
                            XServiceManager.getLitePMService().install(
                                    task.savepath + task.filename, CoocaaApplication.isRoot(), params);
                            break;
                        }
                        default:
                            break;
                    }
                } catch (RemoteException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        });
    }

    private IDownloaderServiceListener.Stub downloaderStub = new IDownloaderServiceListener.Stub() {
        @Override
        public void onReady(final DownloadTask task) throws RemoteException {
            // TODO Auto-generated method stub
            DownloadExtra extra = DownloadExtra.parseJObject(task.extra, DownloadExtra.class);
            boolean hasTask = false;
            synchronized (taskMap) {
                hasTask = taskMap.containsKey(extra.pkgname);
            }
            if (!hasTask) {
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        // TODO Auto-generated method stub
                        updateUI();
                    }
                });
            } else {
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        // TODO Auto-generated method stub
                        downloadlistener.onUpdateStatus(task.url, AppStatus.WAITING);
                    }
                });
            }
            update();
        }

        @Override
        public void onPrepare(final DownloadTask task) throws RemoteException {
            // TODO Auto-generated method stub
        }

        @Override
        public void onStart(final DownloadTask task) throws RemoteException {
            // TODO Auto-generated method stub
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    // TODO Auto-generated method stub
                    datalistener
                            .onRefreshShowInfo(
                                    task.url,
                                    Tools.fixFloat((float) task.info.length / (1024.00f * 1024.00f))
                                            + "MB");
                    downloadlistener.onUpdateStatus(task.url, AppStatus.DOWNLOADING);
                }
            });
            update();
        }

        @Override
        public void onStop(final DownloadTask task) throws RemoteException {
            // TODO Auto-generated method stub
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    // TODO Auto-generated method stub
                    downloadlistener.onUpdateStatus(task.url, AppStatus.DOWNLOAD_PAUSED);
                }
            });
            update();
        }

        @Override
        public void onFinish(final DownloadTask task) throws RemoteException {
            // TODO Auto-generated method stub
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    // TODO Auto-generated method stub
                    downloadlistener.onUpdateStatus(task.url, AppStatus.DOWNLOADED);
                }
            });
            update();
        }

        @Override
        public void onDelete(final DownloadTask task) throws RemoteException {
            // TODO Auto-generated method stub
            DownloadExtra extra = DownloadExtra.parseJObject(task.extra, DownloadExtra.class);
            synchronized (taskMap) {
                taskMap.remove(extra.pkgname);
            }
            updateUI();
        }

        @Override
        public void onProcessInfo(final DownloadTask task, final ProcessInfo info)
                throws RemoteException {
            // TODO Auto-generated method stub
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    // TODO Auto-generated method stub
                    downloadlistener.onUpdatePercent(task.url, info.percent);
                }
            });
        }

        @Override
        public void onError(final DownloadTask task, DownloadError error) throws RemoteException {
            // TODO Auto-generated method stub
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    // TODO Auto-generated method stub
                    downloadlistener.onUpdateStatus(task.url, AppStatus.DOWNLOAD_PAUSED);
                }
            });
            update();
        }
    };

    private ILitePMInstallListener.Stub appPMstub = new ILitePMInstallListener.Stub() {
        @Override
        public void onInstallStart(String apkfile, AppInfo appInfo, final InstallParams params) throws RemoteException {
            // TODO Auto-generated method stub
            DownloadTask task = null;
            synchronized (taskMap) {
                task = taskMap.get(appInfo.pkgName);
            }
            if (task != null) {
                final DownloadTask _task = task;
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        // TODO Auto-generated method stub
                        downloadlistener.onUpdateStatus(_task.url, AppStatus.INSTALLING);
                    }
                });
            }
        }

        @Override
        public void onInstallEnd(String arg0, AppInfo appInfo, int arg2, String arg3, final InstallParams params)
                throws RemoteException {
            // TODO Auto-generated method stub
            DownloadTask task = null;
            synchronized (taskMap) {
                task = taskMap.get(appInfo.pkgName);
                if (task != null && arg2 == 0)
                    XServiceManager.getDownloaderService().delete(task);
            }
            updateUI();
        }
    };

    @Override
    public String getModuleName() {
        // TODO Auto-generated method stub
        return "";
    }
}
